﻿using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using KTVConsole2.Core;
using System.ComponentModel;
using System.Windows.Data;
using NLog;
using WindowsInput;

namespace KTVConsole2.UI
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public static MainWindow Instance;
        public static KtvEngine Engine;
        public static SongPlayedManager Sm;
        public System.Diagnostics.Process pOri;
        public static bool? CanChangeToOthers;
        public static System.Timers.Timer timer;
        Logger logger = LogManager.GetCurrentClassLogger();
        private int flagTimeStart;

        public MainWindow()
        {
            pOri = System.Diagnostics.Process.GetCurrentProcess();
            Instance = this;
            Engine = KtvEngine.GetInstance();
            Sm = SongPlayedManager.GetInstance();
            InitializeComponent();
            lvPlayList.ItemsSource = Engine.PlayList;
            lvSearch.ItemsSource = Engine.SearchList;
            SortDescriptionCollection sdc = lvSearch.Items.SortDescriptions;
            sdc.Add(new SortDescription("StarPinYin", ListSortDirection.Descending));            
            Engine.PlayedRaised += new EventHandler<PlayedRaisedEventArgs>(Engine_PlayedRaised);
            CanChangeToOthers = cbCanChangeToOtherWindow.IsChecked;
            timer = new System.Timers.Timer(5 * 1000);
            timer.Enabled = false;
            timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);
            timer.AutoReset = true;
            if (System.Deployment.Application.ApplicationDeployment.IsNetworkDeployed)
                Version.Content = System.Deployment.Application.ApplicationDeployment.CurrentDeployment.CurrentVersion.ToString();
        }

        void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            if (CanChangeToOthers == true)
            {
                timer.Enabled = false;
                return;
            }
            Util.WINAPI.SetForegroundWindow(pOri.MainWindowHandle);            
        }

        void Engine_PlayedRaised(object sender, PlayedRaisedEventArgs e)
        {
            if (Engine.PlayList.Count < 2)
            {
                return;
            }
            //还有歌曲，播放下一首
            int flagTimeStop = System.Environment.TickCount;
            if ((flagTimeStop - flagTimeStart) > (30 * 1000))
            {
                Sm.AddSong(Engine.PlayList[0]);
                Sm.SaveToXml();
            }
            PlayNext();
        }        

        private void btnReadList_Click(object sender, RoutedEventArgs e)
        {
            ReadPlayList rpl = new ReadPlayList();
            OpenSubForm(rpl);
        }

        private void OpenSubForm(Window form)
        {
            timer.Enabled = false;
            form.ShowDialog();
            if (cbCanChangeToOtherWindow.IsChecked == false)
                timer.Enabled = true;
        }

        private void btnSaveList_Click(object sender, RoutedEventArgs e)
        {
            SavePlayList spl = new SavePlayList();
            OpenSubForm(spl);
        }
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            txtSearch.Focus();
            timer.Enabled = true;
        }

        private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            Engine.Close();
        }

        private void btnNext_Click(object sender, RoutedEventArgs e)
        {
            if (Engine.PlayList.Count < 2)
            {
                Util.Util.TellUser("多点儿点歌。歌太少，没有下首歌了！");
                return;
            }
            Engine.PlayList.RemoveAt(0);
            Play();
        }

        private void txtSearch_TextChanged(object sender, TextChangedEventArgs e)
        {
            if (lvSearch == null) return;
            Engine.SearchSong(txtSearch.Text, cbPlayer.IsChecked, cbSong.IsChecked);
            lvSearch.ItemsSource = Engine.SearchList;
            lblTotalCount.Content = "搜索结果: " + Engine.SearchList.Count;
            if (lvSearch.HasItems)
                lvSearch.SelectedIndex = 0;
        }

        private void cbPlayer_Checked(object sender, RoutedEventArgs e)
        {
            //当窗口打开时，由于设置了默认值，这时会触发check事件。为了确保两个check项都已经初始化了，需要加入这个判断项。否则会由于一个check项没有初始化而摄氏。
            if (cbPlayer != null && cbSong != null)
                txtSearch_TextChanged(null, null);           
        }

        private void cbSong_Checked(object sender, RoutedEventArgs e)
        {
            cbPlayer_Checked(null, null);
        }

        private void btnConfig_Click(object sender, RoutedEventArgs e)
        {
            var config = new Config();
            OpenSubForm(config);
            Engine.SearchSong(txtSearch.Text, cbPlayer.IsChecked, cbSong.IsChecked);
            lvSearch.ItemsSource = Engine.SearchList;
        }

        private void lvPlayList_MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            if (lvPlayList.SelectedItem == null)
                return;
            var pos = lvPlayList.SelectedIndex;
            if (pos == -1)
                return;
            if (pos == 0)
            { Play(); return; }
            if (pos == 1)
            {
                PlayNext();
                return;
            }
            var posTo = 1;
            var from = lvPlayList.SelectedItem as Song;
            Engine.PlayList.RemoveAt(pos);
            Engine.PlayList.Insert(posTo, from);
            lvPlayList.SelectedIndex = posTo;
            lvPlayList.ScrollIntoView(lvPlayList.SelectedItem);
        }

        private void lvPlayList_KeyDown(object sender, KeyEventArgs e)
        {
            switch (e.Key)
            {
                case Key.Delete:
                    e.Handled = true;
                    for (int i = lvPlayList.SelectedItems.Count - 1; i >= 0; i--)
                    {
                        var item = lvPlayList.SelectedItems[i] as Song;
                        Engine.PlayList.Remove(item);
                    }
                    break;
            }
        }

        private void lvSearch_MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            if (lvSearch.SelectedItem == null)
                return;
            var selected = lvSearch.SelectedItem as Song;
            Engine.AddSongToPlayList(selected);
        }

        private void lvPlayList_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {

        }

        private void btnIncreaseVolumn_Click(object sender, RoutedEventArgs e)
        {
            //Engine.IncreaseVolumn();
        }

        private void CommandBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            //MessageBox.Show("can exe");
            e.CanExecute = true;
            //e.Handled = true;
        }

        private void CommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            string cmd = e.Parameter as string;
            cmd = cmd.ToUpper();
            if (cmd == null)
                return;
            timer.Enabled = false;
            switch (cmd)
            {
                case "PLAY":
                    Sm.AddSong(Engine.PlayList[0]);
                    Sm.SaveToXml();
                    Play();
                    break;
                case "PLAYNEXT":
                    int flagTimeStop = System.Environment.TickCount;
                    if ((flagTimeStop - flagTimeStart) > (30 * 1000))
                    {
                        Sm.AddSong(Engine.PlayList[0]);
                        Sm.SaveToXml();
                    }
                    PlayNext();
                    break;
                case "FULLSCREEN":
                    //必须睡会，因为fullscreen是通过键盘按钮实现的。
                    //如果不睡，会因为由于程序运行速度过快，而导至没有按到正确的按键。
                    System.Threading.Thread.Sleep(2000);
                    FullScreen();
                    break;
                case "TOGGLETRACK":
                    System.Threading.Thread.Sleep(2000);
                    ToggleTrack();
                    break;
                case "INPUTSEARCH":
                    txtSearch.Focus();
                    break;
                case "SELECTALL":
                    SelectAll();
                    break;
            }
            if (cbCanChangeToOtherWindow.IsChecked == false)
                timer.Enabled = true;
        }

        private void SelectAll()
        {
            if (!lvSearch.HasItems)
                return;
            int n = 0;
            foreach (Song a in lvSearch.Items)
            {
                if (n++ < 200)
                    Engine.AddSongToPlayList(a);
            }
        }

        private void ToggleTrack()
        {
            Engine.ToggleTrack();
        }

        private void FullScreen()
        {
            Engine.ToggleFullScreen();
        }

        private void PlayNext()
        {
            if (Engine.PlayList.Count < 2)
            {
                Util.Util.TellUser("多点点儿歌！");
                return;
            }
            Engine.PlayList.RemoveAt(0);
            Play();
        }

        private void Play()
        {
            if (Engine.PlayList.Count == 0)
            {
                Util.Util.TellUser("请先点播歌曲！");
                return;
            }
            long duration;
            if (logger.IsDebugEnabled)
            {
                duration = 30 * 1000;
                Engine.Play();
            }
            else
            {
                duration = Engine.Play();
            }
            flagTimeStart = Environment.TickCount;
            TimeSpan tsDuration = new TimeSpan(duration * 10000);
            Song song = Engine.PlayList[0];
            this.Title = string.Format("点歌台 - {0}分{1}秒 - {2} - {3} - {4} - {5}音轨", tsDuration.Minutes, tsDuration.Seconds, song.Star, song.SongName, song.Path, song.AudioCount);
        }

        private void Export()
        {
            if (Engine.PlayList.Count == 0)
            {
                Util.Util.TellUser("请先点歌。现在没有歌曲，所以无法导出");
                return;
            }
            string dir = @"c:\temp";
            if (!System.IO.Directory.Exists(dir))
            {
                System.IO.Directory.CreateDirectory(dir);
            }
            foreach(var song in Engine.PlayList)
            {
                System.IO.File.Copy(song.Path, dir + "\\" + song.SongName + ".mpg", true);
            }
            System.Diagnostics.Process.Start("explorer", dir);
        }


        private void Window_KeyDown(object sender, KeyEventArgs e)
        {
            switch (e.Key)
            {
                case Key.Escape:
                    timer.Enabled = false;
                    var a = Util.Util.TellUser("退出，没按错吧？");
                    if (cbCanChangeToOtherWindow.IsChecked == false)
                        timer.Enabled = true;
                    if (a == MessageBoxResult.OK)
                        this.Close();
                    break;
            }
            //MessageBox.Show("windows key: " + e.Key);
        }
        private void GridViewColumnHeader_Click(object sender, RoutedEventArgs e)
        {
            if (e.OriginalSource is GridViewColumnHeader)
            {
                //Get clicked column
                GridViewColumn clickedColumn = (e.OriginalSource as GridViewColumnHeader).Column;
                if (clickedColumn != null)
                {
                    //Get binding property of clicked column
                    string bindingProperty = (clickedColumn.DisplayMemberBinding as Binding).Path.Path;
                    if (bindingProperty == "SongName")
                        bindingProperty = "SongNamePinYin";
                    if (bindingProperty == "Star")
                        bindingProperty = "StarPinYin";
                    SortDescriptionCollection sdc = lvSearch.Items.SortDescriptions;
                    ListSortDirection sortDirection = ListSortDirection.Ascending;
                    if (sdc.Count > 0)
                    {
                        SortDescription sd = sdc[0];
                        sortDirection = (ListSortDirection)((((int)sd.Direction) + 1) % 2);
                        sdc.Clear();
                    }
                    sdc.Add(new SortDescription(bindingProperty, sortDirection));
                }
            }
        }

        private void lvSearch_KeyDown(object sender, KeyEventArgs e)
        {
            switch (e.Key)
            {
                case Key.Enter:
                    var song = lvSearch.SelectedItem as Song;
                    if (song != null)
                    {
                        Engine.AddSongToPlayList(song);
                    }
                    break;
            }
        }

        private void lvPlayList_KeyDown_1(object sender, KeyEventArgs e)
        {
            switch (e.Key)
            {
                case Key.Enter:
                    if (lvPlayList.SelectedItem == null)
                        break;
                    var pos = lvPlayList.SelectedIndex;
                    if (pos == -1)
                        break;
                    if (pos == 0)
                    {
                        Play();
                        break;
                    }
                    if (pos == 1)
                    {
                        PlayNext();
                        break;
                    }
                    var posTo = 1;
                    var from = lvPlayList.SelectedItem as Song;
                    Engine.PlayList.RemoveAt(pos);
                    Engine.PlayList.Insert(posTo, from);
                    lvPlayList.SelectedIndex = posTo;
                    lvPlayList.ScrollIntoView(lvPlayList.SelectedItem);
                    break;
                case Key.E:
                    var pos2 = lvPlayList.SelectedIndex;
                    if (pos2 == -1)
                        break;
                    if (pos2 == 0)
                        break;
                    var posTo2 = pos2 - 1;
                    var from2 = lvPlayList.SelectedItem as Song;
                    Engine.PlayList.RemoveAt(pos2);
                    Engine.PlayList.Insert(posTo2, from2);
                    lvPlayList.SelectedIndex = posTo2;
                    lvPlayList.ScrollIntoView(lvPlayList.SelectedItem);
                    e.Handled = true;
                    break;
                case Key.D:
                    var pos1 = lvPlayList.SelectedIndex;
                    if (pos1 == -1)
                        break;
                    if (pos1 == Engine.PlayList.Count-1)
                        break;
                    var posTo1 = pos1 + 1;
                    var to1 = lvPlayList.SelectedItem as Song;
                    Engine.PlayList.RemoveAt(pos1);
                    Engine.PlayList.Insert(posTo1, to1);
                    lvPlayList.SelectedIndex = posTo1;
                    lvPlayList.ScrollIntoView(lvPlayList.SelectedItem);
                    e.Handled = true;                    
                    break;
                case Key.Delete:
                    var a = lvPlayList.SelectedItems;
                    var b = new System.Collections.ArrayList(a);
                    foreach (Song c in b)
                    {
                        Engine.PlayList.Remove(c);
                    }
                    break;
            }
        }

        private void txtSearch_PreviewKeyDown(object sender, KeyEventArgs e)
        {
            switch (e.Key)
            {
                case Key.Escape:
                    if (txtSearch.Text == "")
                    {
                        btnPlay.Focus();
                    }
                    else
                    {
                        txtSearch.Text = "";
                    }
                    e.Handled = true;
                    break;
                case Key.Enter:
                    if (lvSearch.HasItems)
                    {
                        var song = lvSearch.SelectedItem as Song;
                        Engine.AddSongToPlayList(song);
                    }
                    e.Handled = true;
                    break;
                case Key.Down:
                    var cursorNow = lvSearch.SelectedIndex;
                    if (cursorNow == -1)
                        break;
                    if (cursorNow == lvSearch.Items.Count - 1)
                        break;
                    cursorNow++;
                    lvSearch.SelectedIndex = cursorNow;
                    lvSearch.ScrollIntoView(lvSearch.SelectedItem);
                    e.Handled = true;
                    break;
                case Key.Up:
                    var cursorNow1 = lvSearch.SelectedIndex;
                    if (cursorNow1 == -1)
                        break;
                    if (cursorNow1 == 0)
                        break;
                    cursorNow1--;
                    lvSearch.SelectedIndex = cursorNow1;
                    lvSearch.ScrollIntoView(lvSearch.SelectedItem);
                    e.Handled = true;
                    break;
            }
        }

        private void Window_Activated(object sender, EventArgs e)
        {
            txtSearch.Focus();
        }

        private void cbCanChangeToOtherWindow_Click(object sender, RoutedEventArgs e)
        {
            CanChangeToOthers = cbCanChangeToOtherWindow.IsChecked;
            if (CanChangeToOthers == true)
                timer.Enabled = false;
            else
                timer.Enabled = true;
        }

        private void BtnSongPlayed_Click(object sender, RoutedEventArgs e)
        {
            WindowSongPlayed wsp = new WindowSongPlayed();
            OpenSubForm(wsp);
        }

        private void BtnVolumnUp_Click(object sender, RoutedEventArgs e)
        {
            KeyboardSimulator sim = new KeyboardSimulator();
            sim.KeyPress(WindowsInput.Native.VirtualKeyCode.VOLUME_UP);
        }

        private void BtnVolumnDown_Click(object sender, RoutedEventArgs e)
        {
            KeyboardSimulator sim = new KeyboardSimulator();
            sim.KeyPress(WindowsInput.Native.VirtualKeyCode.VOLUME_DOWN);
        }

        private void BtnMute_Click_1(object sender, RoutedEventArgs e)
        {
            KeyboardSimulator sim = new KeyboardSimulator();
            sim.KeyPress(WindowsInput.Native.VirtualKeyCode.VOLUME_MUTE);
        }

        private void Hyperlink_RequestNavigate(object sender, System.Windows.Navigation.RequestNavigateEventArgs e)
        {
            System.Diagnostics.Process.Start(e.Uri.ToString());
        }

        private void btnExport_Click(object sender, RoutedEventArgs e)
        {
            Export();
        }

    }
}
